﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Universum.Model.Domain;

namespace Universum.Infrastructure.Persistence
{
	/// <summary>
	/// A generic repository that defines the general
	/// contract that specific implementations will 
	/// have to provide
	/// </summary>
		public interface IRepository
		{
			/// <summary>
			/// Saves or updates a domain entity
			/// </summary>
			/// <typeparam name="ENTITY">The concrete entity type</typeparam>
			/// <param name="entity">The entity instance</param>
			void SaveOrUpdate<ENTITY>(ENTITY entity)
				where ENTITY : DomainEntity;
			/// <summary>
			/// Loads the entity based on it's id
			/// </summary>
			/// <typeparam name="ENTITY">The concrete entity type</typeparam>
			/// <param name="id">The identifier for that entity</param>
			/// <returns></returns>
			ENTITY Load<ENTITY>(Guid id)
				where ENTITY : DomainEntity;
			/// <summary>
			/// Queries for all entities of a specific type.
			/// </summary>
			/// <typeparam name="ENTITY">The concrete entity type</typeparam>
			/// <returns></returns>
			IQueryable<ENTITY> Query<ENTITY>()
				where ENTITY : DomainEntity;
			/// <summary>
			/// 
			/// </summary>
			/// <typeparam name="ENTITY">The concrete entity type</typeparam>
			/// <param name="pageIndex"></param>
			/// <param name="pageSize"></param>
			/// <returns></returns>
			IQueryable<ENTITY> QueryPaged<ENTITY>(int pageIndex, int pageSize)
				where ENTITY : DomainEntity;

			/// <summary>
			/// 
			/// </summary>
			/// <typeparam name="ENTITY">The concrete entity type</typeparam>
			/// <param name="whereQuery">The query selector</param>
			/// <returns></returns>
			IQueryable<ENTITY> Query<ENTITY>(IDomainQuery<ENTITY> whereQuery)
				where ENTITY : DomainEntity;
			/// <summary>
			/// Queries for entities based on specified selector
			/// </summary>
			/// <typeparam name="ENTITY">The concrete entity type</typeparam>
			/// <param name="whereQuery">The query selector</param>
			/// <param name="pageIndex">The page index</param>
			/// <param name="pageSize">The page size</param>
			/// <returns>The page size number of entities from the specified page index</returns>
			IQueryable<ENTITY> QueryPaged<ENTITY>(IDomainQuery<ENTITY> whereQuery, int pageIndex, int pageSize)
				where ENTITY : DomainEntity;

			/// <summary>
			/// Removes the entity from the storage
			/// </summary>
			/// <typeparam name="ENTITY">The concrete entity type</typeparam>
			/// <param name="entity">The entity instance</param>
			void Remove<ENTITY>(ENTITY entity)
				where ENTITY: DomainEntity;
			
		}
	
}
